using System;
using System.Globalization;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;

namespace AntEater.Integration.Attributes
{
    /// <summary>
    /// This attribute provides solution persistence.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    [ComVisibleAttribute(false)]
    public sealed class ProvideSolutionPersistenceAttribute : RegistrationAttribute
    {
        private Guid _packageGuid;
        private string _sectionName;

        /// <summary>
        /// Initializes a new instance of the <see cref="ProvideSolutionPersistenceAttribute"/> class.
        /// </summary>
        /// <param name="packageId">The package id.</param>
        /// <param name="sectionName">Name of the section.</param>
        public ProvideSolutionPersistenceAttribute(string packageId, string sectionName) {

            if (packageId == null) { throw new ArgumentNullException("packageId"); }
            if (sectionName == null) { throw new ArgumentNullException("sectionName"); }

            this._packageGuid = new Guid(packageId);
            this._sectionName = sectionName;
        }

        /// <summary>
        /// Gets the package id.
        /// </summary>
        /// <value>The package id.</value>
        public string PackageId {
            get { return _packageGuid.ToString(); }
        }

        /// <summary>
        /// Gets or sets the name of the section.
        /// </summary>
        /// <value>The name of the section.</value>
        public string SectionName {
            get { return _sectionName; }
        }

        /// <summary>
        /// Gets the registry path.
        /// </summary>
        /// <value>The registry path.</value>
        private string RegistryPath {
            get { return string.Format(CultureInfo.InvariantCulture, "SolutionPersistence\\{0}", _sectionName); }
        }

        /// <summary>
        /// Registers this instance.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void Register(RegistrationContext context) {
            if (context == null) { throw new ArgumentNullException("context"); }

            using (Key childKey = context.CreateKey(this.RegistryPath)) {
                childKey.SetValue(null, _packageGuid.ToString("B"));
            }
        }

        /// <summary>
        /// Unregisters this instance.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void Unregister(RegistrationContext context) {
            if (context == null) { throw new ArgumentNullException("context"); }

            context.RemoveKey(this.RegistryPath);
        }
    }
}

